﻿using System;

namespace Skybot.Extension
{
    /// <summary>
    /// 用于解析的基本读取方法
    /// </summary>
    public static class ParseReadHelper
    {
        #region 基本读取方法



        /// <summary>
        /// 从数组中读取一个double, double 8字节
        /// </summary>
        /// <param name="message">数组</param>
        /// <param name="index">当前读取索引</param>
        /// <returns></returns>
        public static double ReadDouble(this byte[] message, ref int index)
        {
            double result = BitConverter.ToDouble(message, index);
            index += 8;
            return result;
        }

        /// <summary>
        /// 从数组中读取一个int, double4字节
        /// </summary>
        /// <param name="message">数组</param>
        /// <param name="index">当前读取索引</param>
        /// <returns></returns>
        public static int ReadInt32(this byte[] message, ref int index)
        {
            int result = BitConverter.ToInt32(message, index);
            index += 4;
            return result;
        }

        /// <summary>
        /// 从数组中读取一个uint, 4字节
        /// </summary>
        /// <param name="message">数组</param>
        /// <param name="index">当前读取索引</param>
        /// <returns></returns>
        public static uint ReadUInt32(this byte[] message, ref int index)
        {
            uint result = BitConverter.ToUInt32(message, index);
            index += 4;
            return result;
        }

        /// <summary>
        /// 从数组中读取一个Ushort, Ushort 2字节
        /// </summary>
        /// <param name="message">数组</param>
        /// <param name="index">当前读取索引</param>
        /// <returns></returns>
        public static ushort ReadUshort(this byte[] message, ref int index)
        {
            if (message == null) throw new ArgumentNullException("message");
            ushort result = BitConverter.ToUInt16(message, index);
            index += 2;
            return result;
        }
        /// <summary>
        /// 从数组中读取一个字节
        /// </summary>
        /// <param name="message">数组</param>
        /// <param name="index">当前读取索引</param>
        public static byte ReadByte(this byte[] message, ref int index)
        {
            byte result = message[index];
            index += 1;
            return result;
        }

        /// <summary>
        /// 从数组中读取一个ulong, ulong 8字节
        /// </summary>
        /// <param name="message">数组</param>
        /// <param name="index">当前读取索引</param>
        /// <returns></returns>
        public static ulong ReadUlong(this byte[] message, ref int index)
        {
            ulong result = BitConverter.ToUInt64(message, index);
            index += 8;
            return result;
        }
        /// <summary>
        /// 读取一个bool 一字节
        /// </summary>
        /// <param name="message">数组</param>
        /// <param name="index">当前读取索引</param>
        /// <returns></returns>
        public static bool ReadBool(this byte[] message, ref int index)
        {
            bool result = BitConverter.ToBoolean(message, index);
            index += 1;
            return result;
        }

        /// <summary>
        /// 读取一些字节数
        /// </summary>
        /// <param name="message">数组</param>
        /// <param name="index">当前读取索引</param>
        /// <param name="contentLenByte">保存长度的字节长度,默认为1字节最大不超过2字节</param>
        /// <returns></returns>
         public static byte[] ReadBytesContainsLength(this byte[] message, ref int index, int contentLenByte = 1)
         {
             if (message == null) throw new ArgumentNullException("message");
             if (contentLenByte >2) throw new NotSupportedException("最大长度不能超过2");
             int len = 0;
             //读取长度
             switch (contentLenByte) 
             {
                 case 1:
                     len = message[index];
                     index++;
                     break;
                 case 2:
                     len = ReadUshort(message, ref index);
                     break;
             }

             //开始复制数据字节
             var result = new byte[len];
             Array.Copy(message, index, result, 0, len);
             index += len;

             return result;
         }


        /// <summary>
        /// 读取一些字节数
        /// </summary>
        /// <param name="message">数组</param>
        /// <param name="index">当前读取索引</param>
        /// <param name="contentLenByte">保存长度的字节长度,默认为1字节</param>
        /// <returns></returns>
        public static byte[] ReadBytes(this byte[] message, ref int index, int contentLenByte = 0)
        {
            if (message == null) throw new ArgumentNullException("message");
            //指定读取字节长度
            int len = contentLenByte;
            //开始复制数据字节
            var result = new byte[len];
            Array.Copy(message, index, result, 0, len);
            index += len;

            return result;
        }
        /// <summary>
        /// 读取一些字符串  默认使用UTF-8编码
        /// </summary>
        /// <param name="message">数组</param>
        /// <param name="index">当前读取索引</param>
        /// <param name="contentLenByte">保存长度的字节长度,默认为1字节</param>
        /// <returns>返回字符串</returns>
        public static string ReadStringUTF8(this byte[] message, ref int index, int contentLenByte = 1)
        {
            var data = ReadBytes(message, ref index, contentLenByte);
            if (data != null)
            {
                return System.Text.Encoding.UTF8.GetString(data, 0, data.Length);
            }
            return string.Empty;
        }

        /// <summary>
        /// 读取一些字符串  默认使用GBK编码
        /// </summary>
        /// <param name="message">数组</param>
        /// <param name="index">当前读取索引</param>
        /// <param name="contentLenByte">保存长度的字节长度,默认为1字节</param>
        /// <returns>返回字符串</returns>
        public static string ReadStringGBK(this  byte[] message, ref int index, int contentLenByte = 1)
        {
            var data = ReadBytes(message, ref index, contentLenByte);
            if (data != null)
            {
                return System.Text.Encoding.GetEncoding("GBK").GetString(data, 0, data.Length);
            }
            return string.Empty;
        }


        #endregion
    }
}
